package edu.pku.sei.modeler.uml.commands.deployment;

import edu.pku.sei.modeler.model.core.MetaModelElement;
import edu.pku.sei.modeler.model.structure.MetaLink;
import edu.pku.sei.modeler.model.structure.MetaNode;
import edu.pku.sei.modeler.model.uml.Artifacts.Artifact;
import edu.pku.sei.modeler.model.uml.Artifacts.Manifestation;
import edu.pku.sei.modeler.model.uml.BasicComponents.Component;
import edu.pku.sei.modeler.model.uml.Dependencies.Dependency;
import edu.pku.sei.modeler.model.uml.Kernel.Association;
import edu.pku.sei.modeler.model.uml.Kernel.Comment;
import edu.pku.sei.modeler.model.uml.Kernel.Generalization;
import edu.pku.sei.modeler.model.uml.Kernel.UMLClass;
import edu.pku.sei.modeler.model.uml.Nodes.Deployment;
import edu.pku.sei.modeler.model.uml.Nodes.Node;
import edu.pku.sei.modeler.uml.commands.UMLAssociationCreateCommand;
import edu.pku.sei.modeler.uml.commands.UMLCommentLinkCreateCommand;
import edu.pku.sei.modeler.uml.commands.UMLConnectionCreateCommand;
import edu.pku.sei.modeler.uml.commands.UMLConnectionCreateCommandFactory;
import edu.pku.sei.modeler.uml.commands.UMLGeneralizationCreateCommand;
import edu.pku.sei.modeler.uml.commands.umlclass.UMLDependencyCreateCommand;

public class DeploymentDiagramConnectionCreateFactory extends
		UMLConnectionCreateCommandFactory {

	public static final DeploymentDiagramConnectionCreateFactory INSTANCE = new DeploymentDiagramConnectionCreateFactory();

	private DeploymentDiagramConnectionCreateFactory() {

	}

	@Override
	public UMLConnectionCreateCommand createCommand(MetaLink link,
			MetaNode source) {
		UMLConnectionCreateCommand cmd = new UMLConnectionCreateCommand(link,
				source);
		MetaModelElement linkModel = link.getModelElement();
		MetaModelElement sourceModel = source.getModelElement();
		if (sourceModel instanceof Artifact) {
			if (linkModel instanceof Deployment) {
				cmd.setModelCmd(new UMLDependencyCreateCommand(linkModel,
						sourceModel));
			} else if (linkModel instanceof Manifestation) {
				cmd.setModelCmd(new UMLDependencyCreateCommand(linkModel,
						sourceModel));
			} else if (linkModel instanceof Dependency) {
				cmd.setModelCmd(new UMLDependencyCreateCommand(linkModel,
						sourceModel));
			} else if (linkModel instanceof Generalization) {
				cmd.setModelCmd(new UMLGeneralizationCreateCommand(linkModel, sourceModel));
			} else if (linkModel instanceof Association) {
				cmd.setModelCmd(new UMLAssociationCreateCommand(linkModel, sourceModel));
			}
		} else if (sourceModel instanceof Node) {
			if (linkModel instanceof Association) {
				cmd.setModelCmd(new UMLAssociationCreateCommand(linkModel, sourceModel));
			}  else if (linkModel instanceof Generalization) {
				cmd.setModelCmd(new UMLGeneralizationCreateCommand(linkModel, sourceModel));
			} else if (linkModel instanceof Dependency && !(linkModel instanceof Deployment)) {
				cmd.setModelCmd(new UMLDependencyCreateCommand(linkModel,
						sourceModel));
			} 
		} else if (sourceModel instanceof Comment) {
			if (linkModel instanceof Dependency) {
				cmd.setModelCmd(new UMLCommentLinkCreateCommand(link.getModelElement(), source.getModelElement()));
			}
		}

		if (cmd.getModelCmd() == null)
			return null;
		else
			return cmd;
	}

	@Override
	public UMLConnectionCreateCommand completeCommand(
			UMLConnectionCreateCommand command, MetaNode target) {
		MetaModelElement linkModel = command.getLink().getModelElement();
		MetaModelElement targetModel = target.getModelElement();

		if (targetModel instanceof Artifact) {
			if (linkModel instanceof Dependency 
					|| linkModel instanceof Generalization
					|| linkModel instanceof Association) {
				command.setTarget(target);
			}
		} else if (targetModel instanceof Node) {
			if (linkModel instanceof Deployment
					|| linkModel instanceof Association
					|| linkModel instanceof Generalization
					|| linkModel instanceof Dependency) {
				command.setTarget(target);
			}
		} else if (targetModel instanceof Component
				|| targetModel instanceof UMLClass) {
			if (linkModel instanceof Manifestation
					|| linkModel instanceof Dependency) {
				command.setTarget(target);
			}
		} else if (targetModel instanceof Comment) {
			if (linkModel instanceof Dependency) {
				command.setTarget(target);
			}
		}

		if (command.getTarget() == target)
			return command;
		else
			return null;
	}
}
